package com.major.crowd.controller;

import com.major.crowd.api.MysqlRemoteService;
import com.major.crowd.api.RedisRemoteService;
import com.major.crowd.config.ShortMessageProperties;
import com.major.crowd.constant.CrowdConstant;
import com.major.crowd.po.MemberPO;
import com.major.crowd.util.CrowdUtil;
import com.major.crowd.util.ResultEntity;
import com.major.crowd.vo.MemberLoginVO;
import com.major.crowd.vo.MemberVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Controller
public class MemberController {

    @Autowired
    private ShortMessageProperties messageProperties;
    @Autowired
    private RedisRemoteService redisRemoteService;
    @Autowired
    private MysqlRemoteService mysqlRemoteService;

    /**
     * 登出
     * @param session session
     * @return 返回首页
     */
    @RequestMapping("/auth/member/logout")
    public String logout(HttpSession session){
        session.invalidate();
        return "redirect:http://127.0.0.1";
    }

    /**
     * 登录，存入session域
     * @return 用户中心
     */
    @RequestMapping("/auth/member/do/login")
    public String login(
            @RequestParam("loginacct") String loginacct,
            @RequestParam("userpswd") String userpswd,
            ModelMap modelMap,
            HttpSession session
    ){
        //查询
        ResultEntity<MemberPO> resultEntity = mysqlRemoteService.getMemPOByLoginAcctRemote(loginacct);

        //查询出错
        if (ResultEntity.FAILED.equals(resultEntity.getResult())){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,resultEntity.getMessage());
            return "member-login";
        }

        //
        MemberPO memberPO = resultEntity.getData();
        if (memberPO == null){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "member-login";
        }

        String userpswdMysql = memberPO.getUserpswd();
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

        boolean matchesResult = encoder.matches(userpswd, userpswdMysql);
        if (!matchesResult){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "member-login";
        }
        MemberLoginVO memberLoginVO = new MemberLoginVO(memberPO.getId(),memberPO.getUsername(),memberPO.getEmail());
        session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER,memberLoginVO);

        //return "redirect:/auth/member/to/center/page";
        return "redirect:http://localhost/auth/member/to/center/page";
    }

    /**
     * 执行注册
     *
     * @param memberVO 用户注册信息
     * @param modelMap
     * @return 调转到登录界面
     */
    @RequestMapping("/auth/do/member/register")
    public String register(MemberVO memberVO, ModelMap modelMap) {

        //获取手机号，key
        String phoneNum = memberVO.getPhoneNum();
        String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;

        //查询
        ResultEntity<String> valueEntity = redisRemoteService.getRedisValueByKey(key);
        String result = valueEntity.getResult();            //是否查到结果

        //没查到结果
        if (ResultEntity.FAILED.equals(result)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, valueEntity.getMessage());
            return "member-reg";            //返回注册页面
        }


        //取得redis中的验证码
        String redisCode = valueEntity.getData();
        //查询结果为空
        if (redisCode == null) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.ATTR_CODE_NOT_EXISTS);
            return "member-reg";            //返回注册页面
        }

        //取得表单中的验证码
        String formCode = memberVO.getCode();
        //比较验证码，不一致
        if (!Objects.equals(formCode, redisCode)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_INVALID);
            return "member-reg";            //返回注册页面
        }

        // 比较验证码，一致，从redis删除
        redisRemoteService.removeRedisKeyRemote(key);

        // 执行密码加密
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String rawPassword = memberVO.getUserpswd();
        String maturePassword = encoder.encode(rawPassword);
        memberVO.setUserpswd(maturePassword);

        // VO --> PO
        MemberPO memberPO = new MemberPO();
        BeanUtils.copyProperties(memberVO, memberPO);

        // 执行保存
        ResultEntity<String> saveMember = mysqlRemoteService.saveMember(memberPO);
        if (ResultEntity.FAILED.equals(saveMember.getResult())){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, saveMember.getMessage());
            return "member-reg";            //返回注册页面
        }

        // 127.0.0.1     8.129.189.62
        return "redirect:http://127.0.0.1/auth/member/to/login/page";
    }


    /**
     * 发送验证码
     *
     * @param phoneNum
     * @return
     */
    @ResponseBody
    @RequestMapping("auth/member/send/short/message.json")
    public ResultEntity<String> sendMessage(@RequestParam("phoneNum") String phoneNum) {

        //发送验证码到手机
        ResultEntity<String> sendMessageResultEntity = CrowdUtil.sendCodeShortMessage(
                messageProperties.getHost(),
                messageProperties.getPath(),
                messageProperties.getMethod(),
                phoneNum,
                messageProperties.getAppCode(),
                messageProperties.getSign(),
                messageProperties.getSkin()
        );

        //判断发送信息结果
        if (ResultEntity.SUCCESS.equals(sendMessageResultEntity.getResult())) {
            //成功，存入redis
            String code = sendMessageResultEntity.getData();                //获取验证码

            String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
            ResultEntity<String> saveCodeResultEntity = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key, code, 10L, TimeUnit.MINUTES);

            //是否存入成功
            if (ResultEntity.SUCCESS.equals(saveCodeResultEntity.getResult())) {
                return ResultEntity.successWithoutData();
            } else {
                return saveCodeResultEntity;
            }
        } else {
            return sendMessageResultEntity;
        }
    }
}
